<?php

namespace App\Console\Commands\Cruise;

use App\Jobs\Cruise\SelfCheck\TaskExpiredJob;
use App\Models\Cruise\CruiseCheckSelfDetailModel;
use App\Models\Cruise\CruiseCheckSelfTaskModel;
use App\Models\Cruise\CruiseOrderModel;
use App\Models\Cruise\CruiseOrderProcessModel;
use App\Models\Cruise\CruiseTemplateModel;
use App\Models\Kms\User\KmsUser;
use App\Models\Shop\ShopModel;
use App\Remote\Rms\RmsUserRemote;
use App\Service\BaseService;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;

class FixShopSelfCheckHistoryRecordCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'shopSelfCheck:fixHistoryRecord';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '门店自检:修复历史数据';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle(): int
    {
//        $this->info("更新历史模板数据写入系统模板类型");
//        // 更新历史模板数据写入系统模板类型
//        $this->fixShopCheckSelfTemplate();
//
//        $this->info("更新历史表单完成数据写入");
//        // 更新历史表单完成数据写入
//        $this->fixShopCheckSelfFinishForm();
//
//        $this->info("更新历史开店闭店自检 前后时间");
//        // 更新历史开店闭店自检 前后时间
//        $this->fixShopCheckSelfBeforeAfterTime();
//
//        $this->info("更新门店自检历史执行数据");
//        // 更新门店自检历史执行数据
//        $this->fixHistoryExecuteTime();
//
//        $this->info("同步cruise_check_self_detail.id");
//        //同步cruise_check_self_detail.id
//        $this->fixCheckDetailsId();

        $this->info("同步表单状态数据");
        //同步cruise_check_self_detail.id
        $this->fixCheckSelfStatus();

        return 0;
    }

    /**
     * 更新历史表单完成数据写入
     */
    public function fixCheckSelfStatus()
    {
        $baseQuery = CruiseCheckSelfDetailModel::query()
                                               ->with("cruiseOrderProcessRel")
                                               ->where("templateType", CruiseTemplateModel::TYPE_8)
                                               ->where("cruiseOrderId", ">", 0);

        $this->info("重置表单操作数据");

        (clone $baseQuery)->update([
            "status"         => 1,
            "finishTime"     => 0,
            "submitTime"     => 0,
            "submitUid"      => 0,
            "submitUsername" => "",
        ]);

        $this->info("根据表单历史操作重构表单操作数据");

        $baseQuery->chunkById(500, function (Collection $collection) {
            $collection->each(
                function (CruiseCheckSelfDetailModel $cruiseCheckSelfDetailModel) {
                    $this->info("cruiseOrderId : " . $cruiseCheckSelfDetailModel->cruiseOrderId);
                    $cruiseOrderProcessRel = $cruiseCheckSelfDetailModel->cruiseOrderProcessRel;
                    if ($cruiseOrderProcessRel->where("step", ">", CruiseOrderProcessModel::PROCESS_CREATED)
                                              ->isEmpty()) {
                        // 操作记录为空 -> 操作任务置为已过期
                        (new TaskExpiredJob(
                            $cruiseCheckSelfDetailModel->id, $cruiseCheckSelfDetailModel->executeEndTime - time())
                        )->expiredDispatch();
                    } else {
                        // 操作记录 - 获取提交人
                        $submit = $cruiseOrderProcessRel->where(
                            "step", CruiseOrderProcessModel::PROCESS_SUBMITTED
                        )->sortByDesc("id")->first();

                        // 更新完成数据
                        if ($submit) {
                            $submitUser = RmsUserRemote::getRmsUserByIds([$submit->createdByUid],
                                    ['id', 'username'])[0] ?? [];

                            CruiseCheckSelfDetailModel::query()
                                                      ->where("id", $cruiseCheckSelfDetailModel->id)
                                                      ->update([
                                                          "status"         => CruiseCheckSelfDetailModel::STATUS_4,
                                                          "submitUid"      => attributeGet($submit, "id", 0),
                                                          "submitTime"     => $submit->createdAt->timestamp,
                                                          "submitUsername" => attributeGet($submitUser, "username", ""),
                                                      ]);
                        }

                        // 操作记录 - 获取审批记录
                        $review = $cruiseOrderProcessRel->where(
                            "step", CruiseOrderProcessModel::PROCESS_SELF_REVIEWED
                        )->sortByDesc("id")->first();

                        if ($review) {
                            CruiseCheckSelfDetailModel::query()
                                                      ->where("id", $cruiseCheckSelfDetailModel->id)
                                                      ->update([
                                                          "finishTime" => $review->createdAt->timestamp,
                                                          "status"     => CruiseCheckSelfDetailModel::STATUS_10
                                                      ]);
                        }
                    }
                });


        });
    }

    /**
     *  更新历史模板数据写入系统模板类型
     */
    public function fixShopCheckSelfTemplate()
    {
        // 更新历史数据写入系统模板类型
        CruiseCheckSelfTaskModel::query()
                                ->withoutGlobalScope("isDel")
                                ->with("cruiseTemplateRel")
                                ->chunkById(
                                    100,
                                    function (Collection $collection) {
                                        $collection->each(
                                            function (CruiseCheckSelfTaskModel $cruiseCheckSelfTaskModel) {
                                                $sysTemplate = attributeGet(
                                                    $cruiseCheckSelfTaskModel,
                                                    "cruiseTemplateRel.sysTemplate",
                                                    0
                                                );
                                                CruiseCheckSelfTaskModel::query()
                                                                        ->where("id",
                                                                            $cruiseCheckSelfTaskModel->id)
                                                                        ->update([
                                                                            "sysTemplate" => $sysTemplate
                                                                        ]);

                                                CruiseCheckSelfDetailModel::query()->where("taskId",
                                                    $cruiseCheckSelfTaskModel->id)->update([
                                                    "sysTemplate" => $sysTemplate
                                                ]);
                                            });
                                    });
    }

    /**
     * 更新历史表单完成数据写入
     */
    public function fixShopCheckSelfFinishForm()
    {
        $baseQuery = CruiseCheckSelfDetailModel::query()
                                               ->with("cruiseOrderProcessRel")
                                               ->where("templateType", CruiseTemplateModel::TYPE_8)
                                               ->where("status", CruiseCheckSelfDetailModel::STATUS_FINISH)
                                               ->where("finishTime", 0)
                                               ->where("cruiseOrderId", ">", 0);

        $baseQuery->chunkById(100, function (Collection $collection) {
            $collection->each(
                function (CruiseCheckSelfDetailModel $cruiseCheckSelfDetailModel) {
                    $cruiseOrderProcessRel = $cruiseCheckSelfDetailModel->cruiseOrderProcessRel;
                    // 操作记录 - 获取提交人
                    $submit = $cruiseOrderProcessRel->where(
                        "step", CruiseOrderProcessModel::PROCESS_SUBMITTED
                    )->sortByDesc("id")->first();

                    // 更新完成数据
                    if ($submit) {
                        $submitUser = RmsUserRemote::getRmsUserByIds([$submit->createdByUid],
                                ['id', 'username'])[0] ?? [];

                        CruiseCheckSelfDetailModel::query()
                                                  ->where("id", $cruiseCheckSelfDetailModel->id)
                                                  ->update([
                                                      "finishTime"     => $submit->createdAt->timestamp,
                                                      "submitUid"      => attributeGet($submit, "id", 0),
                                                      "submitUsername" => attributeGet($submitUser, "username", ""),
                                                  ]);
                    }

                });


        });
    }


    /**
     * 更新历史开店闭店自检 前后时间
     */
    public function fixShopCheckSelfBeforeAfterTime()
    {
        CruiseCheckSelfTaskModel::query()->whereIn(
            "sysTemplate", [
                CruiseTemplateModel::SYS_TEMPLATE_SELF_CLOSE,
                CruiseTemplateModel::SYS_TEMPLATE_SELF_OPEN,
            ]
        )->where(
            "executeEndAfter", 0
        )->where(
            "executeStartBefore", 0
        )->update([
            "executeEndAfter"    => 3,
            "executeStartBefore" => 3
        ]);
    }

    /**
     * 更新历史数据执行时间
     */
    public function fixHistoryExecuteTime()
    {

        $getRuleCycle = function (CruiseCheckSelfTaskModel $cruiseCheckSelfTaskModel, int $createTime) {
            $carbon = Carbon::createFromTimestamp($createTime);
            switch ($cruiseCheckSelfTaskModel->rule) {
                case CruiseCheckSelfTaskModel::RULE_DAY:
                    $ruleCycleStart = $carbon->clone()->startOfDay()->timestamp;
                    $ruleCycleEnd   = $carbon->clone()->endOfDay()->timestamp;
                    break;
                case CruiseCheckSelfTaskModel::RULE_WEEK:
                    $ruleCycleStart = $carbon->clone()->startOfWeek()->timestamp;
                    $ruleCycleEnd   = $carbon->clone()->endOfWeek()->timestamp;
                    break;
                case CruiseCheckSelfTaskModel::RULE_MONTH:
                    $ruleCycleStart = $carbon->clone()->startOfMonth()->timestamp;
                    $ruleCycleEnd   = $carbon->clone()->endOfMonth()->timestamp;
                    break;
                default:
                    BaseService::throwErr('当前规则暂无法解析 [ ruleType : ' . $cruiseCheckSelfTaskModel->rule . ']');
            }

            return [$ruleCycleStart, $ruleCycleEnd];
        };

        $baseQuery = CruiseCheckSelfDetailModel::query()
                                               ->where("templateType", CruiseTemplateModel::TYPE_8)
                                               ->with([
                                                   "cruiseCheckSelfTaskRel" => function ($query) {
                                                       $query->withoutGlobalScope("isDel");
                                                   }
                                               ])
                                               ->where("executeStartTime", 0)
                                               ->where("executeEndTime", 0);

        $baseQuery->chunkById(100, function (Collection $collection) use ($getRuleCycle) {
            $collection->each(function (CruiseCheckSelfDetailModel $cruiseCheckSelfDetailModel) use ($getRuleCycle) {
                // 周期的开始、结束时间戳
                list($startT, $endT) = $getRuleCycle(
                    $cruiseCheckSelfDetailModel->cruiseCheckSelfTaskRel,
                    $cruiseCheckSelfDetailModel->createdAt->timestamp
                );

                $startTime = strtotime(
                    date('Y-m-d ' . $cruiseCheckSelfDetailModel->cruiseCheckSelfTaskRel->executeStartHis, $startT)
                );
                if ($cruiseCheckSelfDetailModel->cruiseCheckSelfTaskRel->executeStartHis > $cruiseCheckSelfDetailModel->cruiseCheckSelfTaskRel->executeEndHis) {
                    // 结束时间跨天
                    // 09:00 - 01:00
                    $endTime = strtotime(
                            date('Y-m-d ' . $cruiseCheckSelfDetailModel->cruiseCheckSelfTaskRel->executeEndHis,
                                $endT)
                        ) + 86400;
                } else {
                    $endTime = strtotime(
                        date('Y-m-d ' . $cruiseCheckSelfDetailModel->cruiseCheckSelfTaskRel->executeEndHis,
                            $endT
                        )
                    );
                }

                CruiseCheckSelfDetailModel::query()->where("id", $cruiseCheckSelfDetailModel->id)->update([
                    "executeStartTime" => $startTime,
                    "executeEndTime"   => $endTime,
                ]);
            });
        });
    }

    /**
     * 同步cruise_check_self_detail。id
     */
    public function fixCheckDetailsId()
    {
        CruiseCheckSelfDetailModel::query()->with("cruiseCheckDetailsRel")
                                  ->where("templateType", CruiseTemplateModel::TYPE_8)
                                  ->where("cruiseOrderId", ">", 0)
                                  ->where("checkDetailsId", 0)
                                  ->chunkById(100, function (Collection $collection) {
                                      $collection->each(function (CruiseCheckSelfDetailModel $cruiseCheckSelfDetailModel
                                      ) {
                                          CruiseCheckSelfDetailModel::query()
                                                                    ->where("id", $cruiseCheckSelfDetailModel->id)
                                                                    ->update([
                                                                        "checkDetailsId" => attributeGet(
                                                                            $cruiseCheckSelfDetailModel,
                                                                            "cruiseCheckDetailsRel.id",
                                                                            0)
                                                                    ]);
                                      });
                                  });
    }
}
